package com.handinfo.android.uicontrols;

import android.graphics.Color;

import com.handinfo.android.core.graphics.DWFont;
import com.handinfo.android.core.graphics.DWGraphics;
import com.handinfo.android.utils.Tools;

public class DWHyperlink extends DWAbsHyperlink
{
	private final int W_BIAOQING = 20;// 一张切片的宽度及高度
	private final int ANCHOR = Tools.LEFT_TOP;
	//
	private byte[] m_types;// 标记类型
	public char[] m_markTypes;// 超链接类型
	public String[] m_ids;// 默认的Id
	public String[] m_contents_copy;// 解析出来的mark字符，和m_contents_hyper存储的字符串对象是一致的，只是数目，位置不同
	public String[][] m_contents;
	private int[] m_imageIds;
	public int[] m_xs;
	public int[] m_ys;
	public int[] m_endXs;
	private boolean[] m_isBolds;
	private boolean[] m_isUnderLines;
	private int[] m_colors;
	private int m_num_sum;// 具有的Item数目
	private int m_num_hyperLink;// 超链接数目

	public DWHyperlink(String str, int w, int h, int colorDefault, DWFont font, boolean line)
	{
		super(str, w, h, colorDefault, font, line);
	}

	/**
	 * 解释数据，提供外部超链接对象
	 */
	protected void interpretate()
	{
		// 初始化
		int num = 50;// 预计选项的数目
		m_types = new byte[num];
		m_markTypes = new char[num];
		m_ids = new String[num];
		m_contents_copy = new String[num];
		m_contents = new String[num][];
		m_imageIds = new int[num];
		m_xs = new int[num];
		m_ys = new int[num];
		m_endXs = new int[num];
		m_isBolds = new boolean[num];
		m_isUnderLines = new boolean[num];
		m_colors = new int[num];
		// 放置信息，处理换行，mark，pic
		String content = m_content;
		String temp = null;
		int tempX = 0;
		int tempY = 0;// 当前计算的Y
		int startIndex = 0;
		int index = 0;// 指向item索引
		while ((temp = getSplitItemStr(content, startIndex)) != null) {
			byte type = getSplitItemType(temp);
			try {
				switch (type) {
					case TYPE_INTRE_CHANGEROW:// 换行
						// 替换换行符
						content = modifyString(content, temp, "");
						if (tempX > 0) {
							tempX = 0;
							tempY += (m_font.getHeight() + 2);
						}
						break;
					case TYPE_INTRE_STR_NOR:// 普通文字
						m_types[index] = type;
						m_xs[index] = tempX;
						m_ys[index] = tempY;
						m_colors[index] = m_color_nor_default;
						m_contents[index] = getSplitStrs(temp, m_xs[index], m_ys[index], m_w);
						m_endXs[index] = getEndX(m_contents[index], m_xs[index], m_ys[index], m_w);
						tempX = m_endXs[index];
						tempY += (m_contents[index].length - 1) * (m_font.getHeight() + 2);
						//
						index++;
						startIndex += temp.length();
						break;
					case TYPE_INTRE_STR_HYPER:// 超链接文字
						m_types[index] = type;
						m_xs[index] = tempX;
						m_ys[index] = tempY;
						m_markTypes[index] = getMarkType(temp);
						m_ids[index] = getMarkIds(temp);
						m_colors[index] = getMarkColor(temp, m_markTypes[index]);
						m_isBolds[index] = getMarkBold(temp);
						m_isUnderLines[index] = getMarkUnderline(temp);
						String resoveStr = getMarkContent(temp);// 获得超链接内容
						content = modifyString(content, temp, resoveStr);// 替换
						m_contents_copy[index] = resoveStr;
						m_contents[index] = getSplitStrs(resoveStr, m_xs[index], m_ys[index], m_w);
						m_endXs[index] = getEndX(m_contents[index], m_xs[index], m_ys[index], m_w);
						tempX = m_endXs[index];
						tempY += (m_contents[index].length - 1) * (m_font.getHeight() + 2);
						if (m_ids[index] != MARK_VALUE_ID_DEFAULT) {
							m_num_hyperLink++;
						}
						index++;
						startIndex += resoveStr.length();
						break;
					case TYPE_INTRE_PIC:// 图片
						m_types[index] = type;
						int w = W_BIAOQING;
						if (tempX + w > m_w) {
							tempX = 0;
							tempY += (m_font.getHeight() + 2);
						}
						m_xs[index] = tempX;
						m_ys[index] = tempY;
						m_imageIds[index] = getImageId(temp);
						content = modifyString(content, temp, "");// 替换
						m_endXs[index] = m_xs[index] + w;
						tempX = m_endXs[index];
						//
						index++;
						break;
					default:
						throw new IllegalArgumentException("无此参数");
				}
			} catch (Exception e) {
				m_types = new byte[1];
				m_xs = new int[1];
				m_ys = new int[1];
				m_endXs = new int[1];
				m_colors = new int[1];
				m_contents = new String[1][];
				
				m_types[0] = TYPE_INTRE_STR_NOR;
				m_xs[0] = 0;
				m_ys[0] = 0;
				m_colors[0] = m_color_nor_default;
				m_contents[0] = getSplitStrs(content, m_xs[0], m_ys[0], content.length());
				m_endXs[0] = getEndX(m_contents[0], m_xs[0], m_ys[0], content.length());
				m_num_sum = 1;
			}
			
		}
		m_num_sum = index;
	}

	/**
	 * 判断当前数据段是否是超链接类型
	 * 
	 * @param i
	 * @return
	 */
	public boolean isHyper(int i)
	{
		return m_types[i] == TYPE_INTRE_STR_HYPER
				&& m_ids[i] != MARK_VALUE_ID_DEFAULT;
	}

	protected void setTypes()
	{
		if (m_types == null) {
			return;
		}
		char[] types = new char[m_num_hyperLink];
		int index = 0;
		for (int i = 0; i < m_num_sum; i++) {
			if (isHyper(i)) {
				types[index] = m_markTypes[i];
				index++;
			}
		}
		m_types_hyper = types;
	}

	protected void setIds()
	{
		if (m_types == null) {
			return;
		}
		String[] ids = new String[m_num_hyperLink];
		int index = 0;
		for (int i = 0; i < m_num_sum; i++) {
			if (isHyper(i)) {
				ids[index] = m_ids[i];
				index++;
			}
		}
		m_ids_hyper = ids;
	}

	protected void setContents()
	{
		if (m_types == null) {
			return;
		}
		String[] contents = new String[m_num_hyperLink];
		int index = 0;
		for (int i = 0; i < m_num_sum; i++) {
			if (isHyper(i)) {
				contents[index] = m_contents_copy[i];
				index++;
			}
		}
		m_contents_hyper = contents;
	}

	/**
	 * <pic i=2></pic>
	 * 
	 * @param str
	 * @return
	 */
	private int getImageId(String str)
	{
		int index = str.indexOf(combine_pic_start);
		if (index == -1) {
			throw new IllegalArgumentException("无此参数");
		}
		int endIndex = str.indexOf(NOR_BRACKET_RIGHT);
		if (endIndex == -1) {
			throw new IllegalArgumentException("无此参数");
		}
		String num = str.substring(7, endIndex);
		return Integer.parseInt(num);
	}

	/**
	 * 获得从某处起，各个有效的ItemString
	 * 
	 * @param str
	 * @param startIndex
	 * @return
	 */
	private String getSplitItemStr(String str, int startIndex)
	{
		if (startIndex >= str.length()) {
			return null;
		}
		char firstChar = str.charAt(startIndex);
		if (firstChar == NOR_BRACKET_LEFT) {// < 标签文字
			int markstart = str.indexOf(combine_mark_start, startIndex);
			int picstart = str.indexOf(combine_pic_start, startIndex);
			if (markstart == startIndex) {// <mark
				int endindex = str.indexOf(combine_mark_end, startIndex);
				if (endindex != -1) {
					int startindex2 = str.indexOf(combine_mark_start, markstart + combine_mark_start.length());
					if (startindex2 != -1 && endindex > startindex2) {
						return getNorStringFromStart(str, markstart + combine_mark_start.length(), startIndex);
					}
					return str.substring(startIndex, endindex + combine_mark_end.length());
				}
				return getNorStringFromStart(str, markstart + combine_mark_start.length(), startIndex);
			}
			else if (picstart == startIndex) {// <pic
				int endindex = str.indexOf(combine_pic_end, startIndex);
				if (endindex != -1) {
					int startindex2 = str.indexOf(combine_pic_start, picstart + combine_pic_start.length());
					if (startindex2 != -1 && endindex > startindex2) {
						return getNorStringFromStart(str, picstart + combine_pic_start.length(), startIndex);
					}
					return str.substring(startIndex, endindex + combine_pic_end.length());
				}
				return getNorStringFromStart(str, picstart + combine_pic_start.length(), startIndex);
			}
			else {// nor
				return getNorStringFromStart(str, startIndex, startIndex);
			}
		}
		else {
			if (String.valueOf(firstChar).equals(TYPE_CONTENT_CHANGEROW)) {// 换行
				return TYPE_CONTENT_CHANGEROW;
			}
			else {// nor
				return getNorStringFromStart(str, startIndex, startIndex);// 从当前行获得
			}
		}
	}

	/**
	 * 
	 * 从开启处获得普通字符串
	 * 
	 * @param str
	 * @return
	 */
	private String getNorStringFromStart(String str, int startIndex, int subIndex)
	{
		// int markIndex = str.indexOf(combine_mark_start, startIndex);
		// int picIndex = str.indexOf(combine_pic_start, startIndex);
		// int type = (markIndex == -1 ? 0 : 2);
		// type += (picIndex == -1 ? 0 : 1);
		// switch (type) {
		// case 0://markIndex == -1 ，picIndex == -1
		// return str.substring(startIndex, str.length());
		// case 1://markIndex == -1，picIndex != -1 ;
		// return str.substring(startIndex, picIndex);
		// case 2://markIndex != -1，picIndex == -1 ;
		// return str.substring(startIndex, markIndex);
		// case 3://markIndex != -1，picIndex != -1 ;
		// int index = markIndex < picIndex ? markIndex : picIndex;
		// return str.substring(startIndex, index);
		// default:
		// throw new IllegalArgumentException("错误");
		// }

		int changerowIndex = str.indexOf(TYPE_CONTENT_CHANGEROW);
		int markIndex = str.indexOf(combine_mark_start, startIndex);
		int picIndex = str.indexOf(combine_pic_start, startIndex);
		int index = changerowIndex;
		if (markIndex != -1) {
			if (index == -1) {
				index = markIndex;
			}
			else {
				index = markIndex < index ? markIndex : index;
			}
		}
		if (picIndex != -1) {
			if (index == -1) {
				index = picIndex;
			}
			else {
				index = picIndex < index ? picIndex : index;
			}
		}
		if (index == -1 || m_change_row) {
			index = str.length();
		}
		return str.substring(subIndex, index);
	}

	private byte getSplitItemType(String item)
	{
		if (item.equals(TYPE_CONTENT_CHANGEROW)) {
			return TYPE_INTRE_CHANGEROW;
		}
		else if (item.indexOf(combine_pic_start) != -1 && item.indexOf(combine_pic_end) != -1
				&& item.indexOf(combine_pic_end) > item.indexOf(combine_pic_start)
				&& item.indexOf(NOR_BRACKET_RIGHT) < item.indexOf(combine_pic_end)) {
			return TYPE_INTRE_PIC;
		}
		else if (item.indexOf(combine_mark_start) != -1 && item.indexOf(combine_mark_end) != -1
				&& item.indexOf(combine_mark_end) > item.indexOf(combine_mark_start)
				&& item.indexOf(NOR_BRACKET_RIGHT) < item.indexOf(combine_mark_end)) {
			return TYPE_INTRE_STR_HYPER;
		} else {
			return TYPE_INTRE_STR_NOR;
		}
	}

	/**
	 * 获得去除mark标签的文字,<mark t=m,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return
	 */
	private static final char getMarkType(String markStr)
	{
		int typeIndex = markStr.indexOf(String.valueOf(MARK_ATT_TYPE)
				+ String.valueOf(NOR_EQUAL));
		if (typeIndex == -1) {
			return URL_DEFAULT;
		}
		return markStr.charAt(typeIndex + 2);// 需在此处加判断，除了特定类型的类型，其余都是错误
	}

	/**
	 * <mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param content
	 * @return
	 */
	private static final String getMarkIds(String markStr)
	{
		int idIndex = markStr.indexOf(String.valueOf(MARK_ATT_ID) + String.valueOf(NOR_EQUAL));
		if (idIndex == -1) {
			return MARK_VALUE_ID_DEFAULT;
		}
		int startIndex = idIndex + 2;
		int endIndex = markStr.indexOf(NOR_SYMBOL_COMMA, startIndex);
		if (endIndex == -1) {
			endIndex = markStr.indexOf(NOR_BRACKET_RIGHT, startIndex);
		}
		return markStr.substring(startIndex, endIndex);
	}

	/**
	 * 获得标记颜色<mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return
	 */
	private static final int getMarkColor(String markStr, char type)
	{
		int colorIndex = markStr.indexOf(String.valueOf(MARK_ATT_COLOR) + String.valueOf(NOR_EQUAL));
		if (colorIndex == -1) {// 若没有颜色
			switch (type) {
				case URL_ACTORITEM:
					return COLOR_DEFAULT_ACTORITEM;
				case URL_MAP:
					return COLOR_DEFAULT_MAP;
				case URL_PLAYER:
					return COLOR_DEFAULT_PLAY;
				case URL_NPC:
					return COLOR_DEFAULT_NPC;
				case URL_DEFAULT:
				default:
					Tools.debugPrintln("标签类型错误 " + type);
					return COLOR_DEFAULT_NOR;
			}
		}
		else {
			String color = "#FF" + markStr.substring(colorIndex + 2, colorIndex + 8);
			int Icolor = 0;
			try {
//				Icolor = Integer.parseInt(color, 16);
				Icolor = Color.parseColor(color);
			}
			catch (Exception ex) {
				Tools.debugPrintln(ex.toString());
			}
			return Icolor;
		}
	}

	/**
	 * <mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return
	 */
	private static final boolean getMarkBold(String markStr)
	{
		int boldIndex = markStr.indexOf(String.valueOf(MARK_ATT_BOLD)
				+ String.valueOf(NOR_EQUAL));
		if (boldIndex == -1) {
			return false;
		}
		else {
			char bold = markStr.charAt(boldIndex + 2);
			if (bold == '0') {
				return false;
			}
			else {
				return true;
			}
		}
	}

	/**
	 * <mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return
	 */
	private static final boolean getMarkUnderline(String markStr)
	{
		int underlineIndex = markStr.indexOf(String.valueOf(MARK_ATT_UNDERLINE)
				+ String.valueOf(NOR_EQUAL));
		if (underlineIndex == -1) {
			return false;
		}
		else {
			char underline = markStr.charAt(underlineIndex + 2);
			if (underline == '0') {
				return false;
			}
			else {
				return true;
			}
		}
	}

	/**
	 * 获得标记内容<mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return 标示内容
	 */
	private static final String getMarkContent(String markStr)
	{
		int startIndex = markStr.indexOf(NOR_BRACKET_RIGHT) + 1;
		int endIndex = markStr.indexOf(combine_mark_end, startIndex);
		return markStr.substring(startIndex, endIndex);
	}

	/**
	 * 将文字切割成字符串
	 * 
	 * @param temp
	 * @param startX
	 * @param startY
	 * @param w
	 * @return
	 */
	private String[] getSplitStrs(String temp, int startX, int startY, int w)
	{
		if (temp == null) {
			return null;
		}
		int sumW = (int)m_font.stringWidth(temp);

		int num = 1;
//		int left = sumW - (w - startX); 
//		if (left > 0) {
//			num = 1 + (left + w) / w;
		num = (sumW + startX) / w + 1;
//		}
		String[] strs = new String[num];
		if (num == 1) {
			strs = new String[] { temp };
		}
		else {
			int maxW = 0;
			int startIndex = 0;
			char[] chars = temp.toCharArray();
			for (int i = 0; i < strs.length; i++) {
				if (i == 0) {
					maxW = w - startX;
				}
				else {
					maxW = w;
				}
				int endIndex = splitStr(chars, maxW, startIndex);
				strs[i] = temp.substring(startIndex, endIndex);
				startIndex = endIndex;
			}
		}
		return strs;
	}

	private int splitStr(char[] chars, int w, int startIndex)
	{
		int tempW = 0;
		for (int i = startIndex; i < chars.length; i++) {
			int tw = (int)m_font.charWidth(chars[i]);
			tempW += tw;
			if (tempW > w) {
				return i;
			}
		}
		return chars.length;
	}

	/**
	 * 获得结束X位置
	 * 
	 * @param strs
	 * @param startX
	 * @param startY
	 * @param w
	 * @return
	 */
	private int getEndX(String[] strs, int startX, int startY, int w)
	{
		if (strs == null) {
			throw new IllegalArgumentException("空");
		}
		if (strs.length == 1) {// 当行文本
			return (int) (startX + m_font.stringWidth(strs[0]));
		}
		else {
			return (int) (m_font.stringWidth(strs[strs.length - 1]));
		}
	}

	/**
	 * 修正坐标
	 */
	protected void correctXY()
	{
		int index_dis = countHyperIndex(m_index_hyper);
		if (index_dis == -1) {
			return;
		}
		while (m_ys[index_dis] + m_relY < 0) {
			m_relY += (m_font.getHeight() + 2);
		}
		boolean isCollect = false;// 是否修正
		int y = m_ys[index_dis] + m_contents[index_dis].length * (m_font.getHeight() + 2);
		while ((isCollect = y + m_relY < 0)) {// 顶部
			m_relY += (m_font.getHeight() + 2);
		}
		if (!isCollect) {
			while ((isCollect = y + m_relY > m_h)) {// 尾部
				m_relY -= (m_font.getHeight() + 2);
			}
		}
	}

	/**
	 * 获得相应的数据索引
	 * 
	 * @return
	 */
	private int countHyperIndex(int index_hyper)
	{
		if (index_hyper < 0) {
			return -1;
		}
		int index = 0;
		for (int i = 0; i < m_markTypes.length; i++) {
			if (isHyper(i)) {
				if (index == index_hyper) {
					return i;
				}
				index++;
			}
		}
		return -1;
	}

	/**
	 * 获得实际高度
	 */
	public int getRealHeight()
	{
		int lastIndex = m_num_sum - 1;
		lastIndex = lastIndex < 0 ? 0 : lastIndex;
		if (m_types[lastIndex] == TYPE_INTRE_PIC) {
			return m_ys[lastIndex] + (W_BIAOQING > (m_font.getHeight() + 2) ? W_BIAOQING : (m_font.getHeight() + 2));
		}
		return m_ys[lastIndex] + m_contents[lastIndex].length * (m_font.getHeight() + 2);
	}

	/**
	 * 得到实际宽度
	 * @return
	 */
	public int getRealWidth()
	{
		if (m_endXs != null && m_endXs.length > 0) {
			int w = 0;
			for (int i = 0; i < m_endXs.length; i++) {
				if (m_endXs[i] > w) {
					w = m_endXs[i];
				}
			}
			return w;
		}
		return 0;
	}

	public void paintHyperLink(DWGraphics g, int x, int y)
	{
		int index_hyper = countHyperIndex(m_index_hyper);// 获得数据中的
		int ih_image = (((m_font.getHeight() + 2) - W_BIAOQING) >> 1);
		for (int i = 0; i < m_num_sum; i++) {
			int tempY = y + m_ys[i];//
			switch (m_types[i]) {
				case TYPE_INTRE_STR_HYPER:
				case TYPE_INTRE_STR_NOR:
					for (int j = 0, len = m_contents[i].length; j < len; j++) {
						int tempX = 0;
						int endX = m_w;
						if (j == 0) {// 起始位置
							tempX = m_xs[i];
						}
						if (j == len - 1) {
							endX = m_endXs[i];
						}
						paintStr(g, x + tempX, tempY, x + endX, m_contents[i][j],
								m_colors[i], m_isBolds[i], m_isUnderLines[i],
								m_types[i] == TYPE_INTRE_STR_HYPER && i == index_hyper, ANCHOR);
						tempY += (m_font.getHeight() + 2);
					}
					break;
				case TYPE_INTRE_PIC:
					paintImage(g, x + m_xs[i], tempY + ih_image, m_imageIds[i], ANCHOR);
					break;
			}
		}
	}

	private void paintStr(DWGraphics g, int x, int y, int endX, String content,
			int color, boolean isBold, boolean isUnderderLine, boolean isSel,
			int anchor)
	{
		if (content == null) {
			return;
		}
		int w = (int)m_font.stringWidth(content);
		if (isSel) {
			g.setColor(0x4f3c4a);
			g.fillRect(x, y, endX - x, w);
		}
		if (isBold) {
//			g.setClip(x, y, w, H_PRE);
//			g.drawString(content, color, x - 1, y - 1, anchor);
			g.drawShadowString(m_font, content, DWControlsManager.COLOR_STROKE, color, x - 1, y - 1, anchor);
		}
//		g.setClip(x, y, w, H_PRE);
//		g.drawString(content, color, x, y, anchor);
		g.drawShadowString(m_font, content, DWControlsManager.COLOR_STROKE, color, x, y, anchor);
		if (isUnderderLine) {
			int bootomY = (int) (y + m_font.getFontHeight());
			g.drawLine(x, bootomY, endX, bootomY);
		}
	}

	private void paintImage(DWGraphics g, int x, int y, int imageID, int anchor)
	{
		g.drawBitmap(DWControlsManager.getInstance().img_biaoqing[imageID], x, y, W_BIAOQING, W_BIAOQING, 0);
		
//		int clipX = g.getClipX();
//		int clipY = g.getClipY();
//		int clipW = g.getClipWidth();
//		int clipH = g.getClipHeight();
//		int rowIndex = imageID / 4;
//		int colIndex = imageID % 4;
//		g.setClip(x, y, W_BIAOQING, W_BIAOQING);
//		g.drawBitmap(DWControlsManager.getInstance().img_biaoqing[imageID],
//				x - (colIndex * W_BIAOQING), y - (rowIndex * W_BIAOQING), 0);
//		g.setClip(clipX, clipY, clipW, clipH);
	}

}
